package jdesktop.appbar.win32;

import com.sun.jna.*;
import com.sun.jna.win32.StdCallLibrary;

public interface User32 extends StdCallLibrary
{
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);

    int WM_CREATE                       =0x0001;
    int WM_DESTROY                      =0x0002;
    int WM_MOVE                         =0x0003;
    int WM_SIZE                         =0x0005;
    int WM_ACTIVATE                     =0x0006;

    int WM_QUIT                         =0x0012;
    int WM_ERASEBKGND                   =0x0014;
    int WM_GETMINMAXINFO                =0x0024;
    int WM_WINDOWPOSCHANGING            =0x0046;
    int WM_WINDOWPOSCHANGED             =0x0047;
    int WM_DISPLAYCHANGE                =0x007E;
    int WM_NCHITTEST                    =0x0084;
    int WM_SIZING                       =0x0214;
    int WM_MOVING                       =0x0216;
    int WM_ENTERSIZEMOVE                =0x0231;
    int WM_EXITSIZEMOVE                 =0x0232;

    int WMSZ_LEFT           =1;
    int WMSZ_RIGHT          =2;
    int WMSZ_TOP            =3;
    int WMSZ_TOPLEFT        =4;
    int WMSZ_TOPRIGHT       =5;
    int WMSZ_BOTTOM         =6;
    int WMSZ_BOTTOMLEFT     =7;
    int WMSZ_BOTTOMRIGHT    =8;
    
    
    /* Other possible messages
     * Colorization - allow the appbar to draw itself based on the desktop color scheme
     */

    int HTCLIENT        = 1;
    int HTCAPTION           = 2;
    int HTLEFT           =   10;
    int HTRIGHT          =   11;
    int HTTOP            =   12;
    int HTBOTTOM         =   15;

    int /*LRESULT*/ CallWindowProcW(Pointer /*WNDPROC*/ lpWndProc, Pointer /*HWND*/ hWnd, int /*UINT*/msg, int /*WPARAM*/ wParam, int /*LPARAM*/ lParam);

    void GetWindowRect(Pointer hWnd, RECT rc);
    void GetClientRect(Pointer hWnd, RECT rc);

    int /*LRESULT*/ DefWindowProcW(Pointer /*HWND*/ hWnd, int /*UINT*/msg, int /*WPARAM*/ wParam, int /*LPARAM*/ lParam);

    void ClientToScreen(Pointer hWnd, Point point);

    void GetCursorPos(Point pt);

    //int PostMessageA(Pointer hWnd, int uMsg, int wParam, int lParam);

    //int RegisterClassA(WNDCLASS cls);

    /**
     * A {@code }WNDPROC}.
     */
    static interface WndProc extends StdCallCallback
    {
        /**
         * Callback method to handle window messges.
         * @param hWnd      The window the message applies to.
         * @param uMsg      The message identifier, see {@code WM_xxx} in {@link User32}, e.g. {@link User32#WM_ACTIVATE}.
         * @param wParam    A pessage parameter - meaning is message-dependent.
         * @param lParam    A message parameter - meaning is message-dependent.
         * @return  An integer return code. The meaning is message-dependent.
         *
         */
        int callback(Pointer hWnd, int uMsg, int wParam, int lParam);
    }

    /**
     * @see User32#RegisterClassA(User32.WNDCLASS)
     */    
    public static class WNDCLASS extends Structure {
        public int /*UINT*/        style;
        public WndProc /*WNDPROC*/     lpfnWndProc;
        public int         cbClsExtra;
        public int         cbWndExtra;
        public Pointer /*HINSTANCE*/   hInstance;
        public Pointer /*HICON*/       hIcon;
        public Pointer /*HCURSOR*/     hCursor;
        public int /*HBRUSH*/      hbrBackground;
        public WString /*LPCSTR*/      lpszMenuName;
        public WString /*LPCSTR*/      lpszClassName;
    };

    /*
    Pointer CreateWindowExA(
        int dwExStyle,
        String lpClassName,
        String lpWindowName,
        int dwStyle,
        int x, int y, int w, int h,
        Pointer hWndParen, Pointer hMenu,
        Pointer hInstance, Pointer lpParam);
    /*
     <DllImport("User32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function RegisterWindowMessage(ByVal msg As String) As Integer
End Function
     */
    /*UINT*/ int RegisterWindowMessageA(String msgName);

    /*
    static public class MSG extends Structure
    {
        public Pointer  hWnd;
        public int      msg;
        public int      wParam;
        public int      lParam;
        public int      time;
        public int      x;
        public int      y;        
    }


    int GetMessageA(MSG msg, Pointer hWnd, int min, int max);
    int TranslateMessage(MSG msg);
    int DispatchMessageA(MSG msg);
    */

    void SetWindowRgn(Pointer hWnd, Pointer rgn, boolean redraw);

    int UpdateWindow(Pointer hWnd);

    
    int ShowWindow(Pointer hWnd, int nCmdShow);

    int SWP_NOSIZE          =0x0001;
    int SWP_NOMOVE          =0x0002;
    int SWP_NOZORDER        =0x0004;
    int SWP_NOREDRAW        =0x0008;
    int SWP_NOACTIVATE      =0x0010;
    int SWP_FRAMECHANGED    =0x0020;  /* The frame changed: send WM_NCCALCSIZE */
    int SWP_SHOWWINDOW      =0x0040;
    int SWP_HIDEWINDOW      =0x0080;
    int SWP_NOCOPYBITS      =0x0100;
    int SWP_NOOWNERZORDER   =0x0200;  /* Don't do owner Z ordering */
    int SWP_NOSENDCHANGING  =0x0400;  /* Don't send WM_WINDOWPOSCHANGING */

    int SWP_DRAWFRAME       = SWP_FRAMECHANGED;
    int SWP_NOREPOSITION    = SWP_NOOWNERZORDER;

    int SWP_DEFERERASE      =0x2000;
    int SWP_ASYNCWINDOWPOS  =0x4000;

    Pointer HWND_TOP        = Pointer.createConstant(0);
    Pointer HWND_BOTTOM     = Pointer.createConstant(1);
    Pointer HWND_TOPMOST    = Pointer.createConstant(-1);
    Pointer HWND_NOTOPMOST  = Pointer.createConstant(-2);

    int SetWindowPos(Pointer hWnd, Pointer hWndInsertAfter,
            int x, int y, int width, int height, int uFlags);

    int GWL_EXSTYLE = -20;
    int GWL_STYLE = -16;
    int GWL_WNDPROC = -4;
    int GWL_HINSTANCE = -6;
    int GWL_ID = -12;
    int GWL_USERDATA = -21;
    int DWL_DLGPROC = 4;
    int DWL_MSGRESULT = 0;
    int DWL_USER = 8;

    int WS_OVERLAPPED = 0x00000000;
    int WS_POPUP = 0x80000000;
    int WS_CHILD = 0x40000000;
    int WS_MINIMIZE = 0x20000000;
    int WS_VISIBLE = 0x10000000;
    int WS_DISABLED = 0x08000000;
    int WS_CLIPSIBLINGS = 0x04000000;
    int WS_CLIPCHILDREN = 0x02000000;
    int WS_MAXIMIZE = 0x01000000;
    int WS_CAPTION = 0x00C00000;     /* WS_BORDER | WS_DLGFRAME  */
    int WS_BORDER = 0x00800000;
    int WS_DLGFRAME = 0x00400000;
    int WS_VSCROLL = 0x00200000;
    int WS_HSCROLL = 0x00100000;
    int WS_SYSMENU = 0x00080000;
    int WS_THICKFRAME = 0x00040000;
    int WS_GROUP = 0x00020000;
    int WS_TABSTOP = 0x00010000;

    int WS_MINIMIZEBOX = 0x00020000;
    int WS_MAXIMIZEBOX = 0x00010000;

    int WS_TILED = WS_OVERLAPPED;
    int WS_ICONIC = WS_MINIMIZE;
    int WS_SIZEBOX = WS_THICKFRAME;

    /*
    * Common Window Styles
    */
    int WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED |
            WS_CAPTION |
            WS_SYSMENU |
            WS_THICKFRAME |
            WS_MINIMIZEBOX |
            WS_MAXIMIZEBOX);

    int WS_POPUPWINDOW = (WS_POPUP |
            WS_BORDER |
            WS_SYSMENU);

    int WS_CHILDWINDOW = (WS_CHILD);
    int WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW;

    int WS_EX_DLGMODALFRAME = 0x00000001;
    int WS_EX_NOPARENTNOTIFY = 0x00000004;
    int WS_EX_TOPMOST = 0x00000008;
    int WS_EX_ACCEPTFILES = 0x00000010;
    int WS_EX_TRANSPARENT = 0x00000020;

    int WS_EX_MDICHILD = 0x00000040;
    int WS_EX_TOOLWINDOW = 0x00000080;
    int WS_EX_WINDOWEDGE = 0x00000100;
    int WS_EX_CLIENTEDGE = 0x00000200;
    int WS_EX_CONTEXTHELP = 0x00000400;

    int WS_EX_RIGHT = 0x00001000;
    int WS_EX_LEFT = 0x00000000;
    int WS_EX_RTLREADING = 0x00002000;
    int WS_EX_LTRREADING = 0x00000000;
    int WS_EX_LEFTSCROLLBAR = 0x00004000;
    int WS_EX_RIGHTSCROLLBAR = 0x00000000;

    int WS_EX_CONTROLPARENT = 0x00010000;
    int WS_EX_STATICEDGE = 0x00020000;
    int WS_EX_APPWINDOW = 0x00040000;


    int WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
    int WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);

    int WS_EX_LAYERED = 0x00080000;

    int WS_EX_NOINHERITLAYOUT = 0x00100000;
    int WS_EX_LAYOUTRTL = 0x00400000;

    int WS_EX_COMPOSITED = 0x02000000;
    int WS_EX_NOACTIVATE = 0x08000000;

    int GetWindowLongW(Pointer hWnd, int nIndex);
    int SetWindowLongW(Pointer hWnd, int nIndex, int dwNewLong);
    int SetWindowLongW(Pointer hWnd, int nIndex, Pointer dwNewLong);
    int SetWindowLongW(Pointer hWnd, int nIndex, Callback dwNewLong);

    static public class Point extends Structure
    {
        public int x;
        public int y;
    }

    static public class MinMaxInfo extends Structure
    {
        public Point reserved;
        public Point ptMaxSize;
        public Point ptMaxPosition;
        public Point ptMinTrackSize;
        public Point ptMaxTrackSize;

        public MinMaxInfo(Pointer p)
        {
            super(p);
        }
    }

    int FillRect(int hdc, RECT rc, int brush);

}
